<?php
/**
 * 统一缓存服务类
 * 整合app/service/CacheService.php和extend/service/CacheService.php的功能
 */

declare(strict_types=1);

namespace app\service;

use think\facade\Cache;
use think\facade\Request;
use think\facade\Config;

class CacheService
{
    // 缓存时间常量
    const DEFAULT_EXPIRE = 3600;    // 1小时
    const SHORT_EXPIRE = 300;       // 5分钟
    const MEDIUM_EXPIRE = 1800;     // 30分钟
    const LONG_EXPIRE = 86400;      // 24小时

    /**
     * 获取缓存键（智能生成）
     */
    public static function getCacheKey(string $prefix, array $params = []): string
    {
        $baseKey = $prefix;
        
        // 添加用户权限信息（基于用户身份）
        $userId = session("user_id") ?: Request::param("user_id", 0);
        if ($userId > 0) {
            // 获取用户权限信息
            $userAuth = self::getUserAuth($userId);
            $baseKey .= ":user_{$userId}_dept_{$userAuth["department_id"]}_group_{$userAuth["group_id"]}";
        }
        
        // 添加筛选参数
        foreach (["keyword", "status", "level", "department_id", "type"] as $param) {
            if (isset($params[$param]) && $params[$param] !== null && $params[$param] !== "") {
                $baseKey .= ":{$param}_" . md5((string)$params[$param]);
            }
        }
        
        return md5($baseKey);
    }

    /**
     * 获取用户权限信息
     */
    private static function getUserAuth(int $userId): array
    {
        $cacheKey = "user_auth:{$userId}";
        return Cache::get($cacheKey, [
            "department_id" => 0,
            "group_id" => 0,
            "user_id" => $userId
        ]);
    }

    /**
     * 智能缓存策略
     */
    public static function smartCache(string $prefix, callable $callback, array $options = [])
    {
        $ttl = $options["ttl"] ?? self::SHORT_EXPIRE;  // 默认5分钟
        $useCache = $options["use_cache"] ?? true;      // 默认启用缓存
        $forceRefresh = $options["force_refresh"] ?? false; // 强制刷新

        // 缓存键生成
        $params = $options["params"] ?? [];
        $cacheKey = self::getCacheKey($prefix, $params);
        
        // 检查缓存
        if ($useCache && !$forceRefresh && Request::method() === "GET") {
            $cachedData = self::get($cacheKey);
            if ($cachedData !== null) {
                return [
                    "data" => $cachedData,
                    "cached" => true,
                    "cache_key" => $cacheKey,
                    "ttl" => $ttl,
                    "source" => "cache"
                ];
            }
        }

        // 执行查询
        $data = $callback();

        // 缓存结果
        if ($useCache && Request::method() === "GET" && !empty($data)) {
            self::set($cacheKey, $data, $ttl);
            // 关联标签用于批量清理
            Cache::tag($prefix, [$cacheKey]);
        }

        return [
            "data" => $data,
            "cached" => false,
            "cache_key" => $cacheKey,
            "ttl" => $ttl,
            "source" => "database"
        ];
    }

    /**
     * 清除相关缓存
     */
    public static function clearRelatedCache(string $prefix, ?int $userId = null): bool
    {
        try {
            // 清除标签缓存
            Cache::clearTag($prefix);
            
            // 清除用户相关缓存
            if ($userId) {
                $auth = self::getUserAuth($userId);
                $patterns = [
                    "{$prefix}:user_{$userId}_dept_{$auth["department_id"]}_group_{$auth["group_id"]}",
                    "user_auth:{$userId}"
                ];
                
                foreach ($patterns as $pattern) {
                    Cache::delete(md5($pattern));
                }
            }
            
            return true;
        } catch (\Exception $e) {
            error_log("缓存清理失败: " . $e->getMessage());
            return false;
        }
    }

    /**
     * 缓存统计
     */
    public static function getCacheStats(): array
    {
        return [
            "prefix" => "crm_cache_stats",
            "hit_rate" => Cache::get("crm_cache_hit_rate", 0),
            "total_requests" => Cache::get("crm_cache_requests", 0),
            "cache_hits" => Cache::get("crm_cache_hits", 0),
            "cache_misses" => Cache::get("crm_cache_misses", 0)
        ];
    }
}
